﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IceTea.Domain.Models;

namespace IceTea.Domain
{
    /// <summary>
    /// RoleProfile is sotring project/team roles for one user
    /// This will generated and stored for one session, used by the controller to get one user's role and permissions
    /// 
    /// An User could has been involved in multiple products, joined in multiple teams of any product, 
    /// and played as multiple roles in any team
    /// </summary>
    [Serializable]
    public class RoleProfile
    {
        public int UserId { get; set; }
        public bool IsSuperAdmin { get; set; }
        public int CurrentProductId { get; set; }
        public string CurrentProductName { get; set; }
        public int CurrentTeamId { get; set; }

        //<ProductId, ProductProfile> => ProductProfile as element for each product
        public IDictionary<int,  ProductProfile> ProductProfiles { get; set; }

        /// <summary>
        /// The TeamsProfiles of a dedicated product for dedicated user
        /// </summary>
        [Serializable]
        public class ProductProfile
        {
            public int ProductId { get; set; }
            public bool IsAdmin { get; set; }
            //<TeamId, TeamProfile> => TeanProfile as element for each Team
            public IDictionary<int, TeamProfile> TeamProfiles { get; set; }
        }

        /// <summary>
        /// The Roles of a dedicated team for dedicated user
        /// </summary>
        [Serializable]
        public class TeamProfile
        {
            public int TeamId { get; set; }
            //Roles of the team
            public IList<int> Roles { get; set; }
        }

        public static RoleProfile ReadRoleProfile(string username)
        {
            if (string.IsNullOrEmpty(username))
                throw new ArgumentNullException("username", "User Name should not be null or empty");

            using (IceTeaEntities ite = new IceTeaEntities())
            {
                //verify the user is exist
                var user = (from u in ite.Users
                            where u.UserName == username
                            select u).FirstOrDefault();
                if (user == null)
                    throw new ArgumentException("Specified user name is not found");

                //initialize the RoleProfile 
                RoleProfile rp = new RoleProfile()
                {
                    UserId = user.Id,
                    IsSuperAdmin = user.SuperAdmin,
                    CurrentProductId = user.CurProdId.HasValue? user.CurProdId.Value : -1,
                    CurrentTeamId = user.CurTeamId.HasValue? user.CurTeamId.Value : -1,
                    ProductProfiles = new Dictionary<int, ProductProfile>()
                };

                //Get the current project name
                if (rp.CurrentProductId >= 0)
                {
                    rp.CurrentProductName = ite.Products.Where(p => p.Id == rp.CurrentProductId)
                                                .Select(p => p.Name).SingleOrDefault();
                }
                else
                {
                    rp.CurrentProductName = string.Empty;
                }

                //get the project/team/roles info from Db
                var results = ite.uspGetUserRoles(user.Id);

                //loop through the Team/Role s results and put them in the RoleProfile
                foreach(uspGetUserRoles_Result r in results.ToList())
                {
                    if (!rp.ProductProfiles.ContainsKey(r.ProductId.Value))
                    {
                        rp.ProductProfiles.Add(
                            r.ProductId.Value,
                            new ProductProfile
                            {
                                 ProductId = r.ProductId.Value,
                                 IsAdmin = false,
                                 TeamProfiles = new Dictionary<int, TeamProfile>()
                            });
                    }
                    if (!rp.ProductProfiles[r.ProductId.Value].TeamProfiles.ContainsKey(r.TeamId))
                    {
                        rp.ProductProfiles[r.ProductId.Value].TeamProfiles.Add(
                            r.TeamId,
                            new TeamProfile()
                            {
                                TeamId = r.TeamId,
                                Roles = new List<int>(),
                            });
                    }

                    rp.ProductProfiles[r.ProductId.Value].TeamProfiles[r.TeamId].Roles.Add(r.RoleId);
                }

                //get the admin info for each project
                var admins = (from pa in ite.ProductAdmins
                              where pa.UserId == user.Id
                              select pa.ProductId).ToList();
                foreach (int proid in admins)
                {
                    if (rp.ProductProfiles.ContainsKey(proid))
                    {
                        rp.ProductProfiles[proid].IsAdmin = true;
                    }
                }

                return rp;

            }
        }
    }

    
}
